/*
 * @Description: cron表达式验证
 * @Author: DHL
 * @Date: 2022-04-14 14:54:15
 * @LastEditors: DHL
 * @LastEditTime: 2022-11-23 08:56:38
 */

import CronParser from 'cron-parser'

export const WEEK_MAP_EN: any = {
  SUN: '0',
  MON: '1',
  TUE: '2',
  WED: '3',
  THU: '4',
  FRI: '5',
  SAT: '6'
}

export const replaceWeekName = (c: any) => {
  // console.info('after: ' + c)
  if (c) {
    Object.keys(WEEK_MAP_EN).forEach((k) => {
      c = c.replace(new RegExp(k, 'g'), WEEK_MAP_EN[k])
    })
    c = c.replace(new RegExp('7', 'g'), '0')
  }
  // console.info('after: ' + c)
  return c
}

export default (rule: object, value: string, callback: Function) => {
  // 没填写就不校验
  if (!value) {
    callback()
    return true
  }

  const values = value.split(' ').filter((item: any) => !!item)
  if (values.length > 7) {
    callback(new Error('cron表达式最多7项'))
    return false
  }
  // 检查第7项
  let e = value
  if (values.length === 7) {
    const year = replaceWeekName(values[6])
    if (year !== '*' && year !== '?') {
      let yearValues: any = []
      if (year.indexOf('-') >= 0) {
        yearValues = year.split('-')
      } else if (year.indexOf('/')) {
        yearValues = year.split('/')
      } else {
        yearValues = [year]
      }
      // console.info(yearValues)
      // 判断是否都是数字
      const checkYear = yearValues.some((item: any) => isNaN(item))
      if (checkYear) {
        callback(new Error('cron表达式参数[年]错误:' + year))
        return false
      }
    }
    // 取其中的前六项
    e = values.slice(0, 6).join(' ')
  }
  // 6位 没有年
  // 5位没有秒、年
  let result = true
  try {
    const iter = CronParser.parseExpression(e)
    iter.next()
    callback()
  } catch (e) {
    callback(new Error('cron表达式错误:' + e))
    result = false
  }
  return result
}
